import { MessageConstant, Key } from "./WorkerMessageConstant"

export class WorkerManager {
    private _worker: WechatMiniprogram.Worker | undefined
    private _isRunning = false
    private _terminateTimeoutId: number | undefined
    private _terminateResolveFun: ((value: boolean | PromiseLike<boolean>) => void) | undefined

    postMessage(message: WechatMiniprogram.IAnyObject) {
        this._worker?.postMessage(message)
    }
    /**
     * 当前是否有worker在运行
     * */
    isRunning() {
        return this._isRunning
    }
    /**
     * 结束当前 Worker 线程
    */
    terminate() {
        return new Promise<boolean>((resolve, _reject) => {
            if (this._worker) {
                this._terminateResolveFun = resolve
                const messageObj: Record<string, any> = new Object();
                messageObj[Key.FUNC] = MessageConstant.MSG_TERMINATE;
                this._worker?.postMessage(messageObj)
                //创建超时，
                this._terminateTimeoutId = setTimeout(() => {
                    this._terminateWorker()
                }, 1000);
            } else {
                resolve(true)
            }
        })
    }
    /**
     * 运行 Worker 线程
     * @param scriptPath  worker 的入口文件路径，绝对路径,举例子：'workers/index.js'
    */
    run(scriptPath: string) {
        if (this._isRunning) {
            return false
        }
        this._worker = wx.createWorker(scriptPath, {
            useExperimentalWorker: true
        })
        this._isRunning = true
        const that = this;
        this._worker.onMessage(function (msg: Record<string, any>) {
            if (msg[Key.FUNC] === MessageConstant.MSG_FINISHED) {//work任务已完成
                that._terminateWorker()
            }
            for (let i = 0; i < that._messageCallbackList.length; i++) {
                that._messageCallbackList[i](msg)
            }
        })
        this._worker.onProcessKilled(function () {
            console.log("worker被终止了");
            that._terminateWorker()
        })
        return true
    }
    private _messageCallbackList: ((msg: Record<string, any>) => void)[] = []
    addMessageCallback(callback: (msg: Record<string, any>) => void) {
        if (this._messageCallbackList.indexOf(callback) >= 0) {
            return
        }
        this._messageCallbackList.push(callback)
    }
    removeMessageCallback(callback: (msg: Record<string, any>) => void) {
        const index = this._messageCallbackList.indexOf(callback)
        if (index >= 0) {
            this._messageCallbackList.splice(index, 1)
        }
    }


    /**
     * 销毁当前worker
     * **/
    private _terminateWorker() {
        if (this._terminateResolveFun) {
            this._terminateResolveFun(true)
            this._terminateResolveFun = undefined
        }
        if (this._terminateTimeoutId != undefined) {
            clearTimeout(this._terminateTimeoutId)
            this._terminateTimeoutId = undefined
        }
        this._worker?.terminate()
        this._worker = undefined
        this._isRunning = false
    }


}

export const workerInstance = new WorkerManager()